﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
using WPFChat.Properties;
using System.Net.Sockets;


namespace WPFChat.Model
{
    public class Client:IClient
    {

        private UdpClient _udpClient;
        private IPEndPoint _groupEp;
        private const int Port = 24113;
        public IPEndPoint IpEndPoint { get; private set; }

        public Client()
        {
            Debug.WriteLine(Resources.Client_Client__INFO__Client_started);
            _udpClient = new UdpClient()
                {
                    ExclusiveAddressUse = false,
                    EnableBroadcast = true
                };
            
            IpEndPoint = new IPEndPoint(IPAddress.Broadcast, Port);

            _groupEp = new IPEndPoint(IPAddress.Any, Port);
            _udpClient.Client.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.ReuseAddress, 1);
            _udpClient.Client.Bind(_groupEp);
            try
            {
                _udpClient.BeginReceive(new AsyncCallback(Receive), null);
                Debug.WriteLine(Resources.Client_Client__INFO__Client_listening);
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.ToString());
            }
        }
        
        public event MessageReceivedHandler MessageReceivedEvent;

        public void Send(Message message)
        {
            Debug.WriteLine(Resources.Client_Send__INFO__Message_sent);
            Debug.Write(message.Content);

            //Serialize and send
            var xmlSerializer = new XmlSerializer(typeof(Message));
            var sw = new StringWriter();
            xmlSerializer.Serialize(sw, message);
            Debug.WriteLine(sw.ToString());

            byte[] sendByteMessage = Encoding.ASCII.GetBytes(sw.ToString()); 
            _udpClient.SendAsync(sendByteMessage, sendByteMessage.Length, IpEndPoint);
        }

        private void Receive(IAsyncResult result)
        {
            if (MessageReceivedEvent != null)
            {
                byte[] received = _udpClient.EndReceive(result, ref _groupEp);
                var xmlSerializer = new XmlSerializer(typeof(Message));
                var message = (Message) xmlSerializer.Deserialize(new StringReader(Encoding.ASCII.GetString(received)));

                MessageReceivedEvent(message);

                Debug.WriteLine(Resources.Client_Receive__INFO__Message_received_);
                Debug.Write(Encoding.UTF8.GetString(received));
                Debug.WriteLine(Resources.Client_Receive_Message_object_content__ + message.Content);
            }

            
            _udpClient.BeginReceive(new AsyncCallback(Receive),null);
        }


    }
}
